#ifndef __PNN_LOG__H
#define __PNN_LOG__H

#include <cstdio>
#include <sstream>
#include <string>

#define PNN_LOG_INFO() PanNN::PanNN_Log_Message(__FILE__, __LINE__, __FUNCTION__, __DATE__, __TIME__, "INFO").stream()
#define PNN_LOG_WARNING() \
    PanNN::PanNN_Log_Message(__FILE__, __LINE__, __FUNCTION__, __DATE__, __TIME__, "WARN").stream()
#define PNN_LOG_ERROR() PanNN::PanNN_Log_Message(__FILE__, __LINE__, __FUNCTION__, __DATE__, __TIME__, "ERROR").stream()
#define PNN_LOG(level) PNN_LOG_##level()

namespace PanNN {
class PanNN_Log_Message {
   public:
    PanNN_Log_Message(const char *file, int line, const char *function, const char *date, const char *time,
                      const char *level) {
        m_stream << "[" << date << " " << time << "][" << file << "] "
                 << "[" << function << " (" << line << ")][" << level << "] ";
    }

    ~PanNN_Log_Message() {
        m_stream << std::endl;
        std::string str_newline(m_stream.str());
        fprintf(stderr, "%s", str_newline.c_str());
        fflush(stderr);
    }

    std::ostream &stream() { return m_stream; }

   private:
    std::ostringstream m_stream;
};
}  // namespace PanNN

#endif  // __PNN_LOG__H
